import * as echarts from 'echarts';
import { onUnmounted, reactive, Ref, shallowRef, watch, onActivated, onDeactivated } from 'vue';

// 定义一个策略借口，方便具体策略的切换实现
export interface ChartStrategy {
   getOptions: () => echarts.EChartsOption;
}

// 自定义 vue 钩子函数，用于管理 echarts 实例
export function useECharts(
   chartRef: Ref<HTMLElement | null>, // 图表的引用
   initOptions: echarts.EChartsOption, // 初始化配置
   theme?: string | object | null, // 可选项 设置 echarts 主题
   opts?: echarts.EChartsInitOpts, // 可选项 echarts 初始化配置项
   strategy?: ChartStrategy // 可选项 策略模式，用于动态切换图表类型
) {
   // 使用 shallowRef 创建一个响应式引用，用于保存 echarts 实例 ；避免在组件内部修改对象属性导致视图更新
   const chartInstance = shallowRef<echarts.EChartsType | null>(null);

   // 使用 ref 创建一个响应式引用，用于保存图表的配置项
   const options = reactive<echarts.EChartsOption>(initOptions as echarts.EChartsOption);

   // 初始化图表实例
   const initChart = () => {
      if (chartRef.value && !chartInstance.value) {
         // 初始化图表 echarts 并赋值给 chartInstance
         chartInstance.value = echarts.init(chartRef.value, theme, opts);
         // 设置图表初始项
         chartInstance.value.setOption(options);
      }
   };

   // 更新图表配置项选项的函数
   const updateChartOptions = (newOptions: echarts.EChartsOption) => {
      // 第一种方式：直接覆盖 options
      /**
        // 更新图表配置项
         Object.assign(options, newOptions);
         // 更新图表实例配置项
         chartInstance.value?.setOption(options);
       */
      // 第二种方式：使用新的选项更新图表，不合并现有配置项并延迟更新以优化性能
      if (chartInstance.value) {
         chartInstance.value.setOption(newOptions, { notMerge: true, lazyUpdate: true });
      }
   };

   // 根据窗口尺寸调整图表大小
   const handleRisize = () => {
      chartInstance.value?.resize();
   };

   // 下载为 png 图片
   const downloadChartImg = (filename: string = 'chart.png') => {
      if (chartInstance.value) {
         const base64 = chartInstance.value.getDataURL({
            type: 'png',
            pixelRatio: 2,
            backgroundColor: '#fff',
         });
         const link = document.createElement('a');
         link.href = base64;
         link.download = filename;
         link.click();
      }
   };

   // 销毁图表实例，清空引用 释放内存
   const disposeChart = () => {
      chartInstance.value?.dispose(); // echarts 中 dispose 销毁图表实例
      chartInstance.value = null; // 清空引用, 避免内存泄露
   };

   // 监听 options 变化，发生变化时更新图表配置项
   watch(options as echarts.EChartsOption, updateChartOptions, { deep: true });

   // 组件卸载时移除事件监听器并销毁图表实例
   onUnmounted(() => {
      window.removeEventListener('resize', handleRisize); // 移除窗口尺寸监听
      disposeChart();
   });

   // 组件激活时重新初始化图表实例 并添加事件监听
   onActivated(() => {
      if (!chartInstance.value) initChart(); // 初始化图表实例
      window.addEventListener('resize', handleRisize); // 添加窗口尺寸监听
   });

   // 组件停用时移除事件监听 并销毁图表实例
   onDeactivated(() => {
      window.removeEventListener('resize', handleRisize);
      disposeChart();
   });

   // 返回图表实例和配置项
   return {
      chartInstance, // 图表实例
      options, // 图表配置项
      updateChartOptions, // 更新图表配置项
      downloadChartImg, // 下载图片
      initChart, // 初始化图表实例
      disposeChart, // 销毁图表实例
   };
}
